from rest_framework import serializers
from users.models import User
from oauth.models import OAuthQQUser
import re
from rest_framework_jwt.settings import api_settings
from django.conf import settings
from django_redis import get_redis_connection
from itsdangerous import TimedJSONWebSignatureSerializer as TJS



class OauthSerializer(serializers.ModelSerializer):

    #显示指明字段

    sms_code = serializers.CharField(max_length=6,min_length=6,write_only=True)# 不需要返回给前端 只参与反序列化验证过程
    access_token = serializers.CharField(write_only=True)
    mobile = serializers.CharField(max_length=11,min_length=11) #重写手机号，忽略唯一值
    token = serializers.CharField(read_only=True)
    username = serializers.CharField(read_only=True)

    class Meta:
        model = User
        fields = ('mobile','password','sms_code','access_token','token','username')
        extra_kwargs = {
            'password':{
                'write_only':True,
                'max_length':20,
                'min_length':8
            }
        }
        # 验证手机号格式
    def validate_mobile(self,value):
        if not re.match(r'^1[3-9]\d{9}$',value):
            raise serializers.ValidationError('手机号不匹配')

        return value

        # 多字段验证
    def validate(self,attrs):
        # 短信验证码判断
        # 1获取缓存中短信验证码
        conn = get_redis_connection('sms_code')
        real_sms_code = conn.get('sms_code_%s' % attrs['mobile'])

        # 2判断短信验证码是否失效
        if real_sms_code is None:
            raise serializers.ValidationError('短信验证码失效')

        # 3对比用户输入的短信验证码
        if attrs['sms_code'] != real_sms_code.decode():
            raise serializers.ValidationError('输入的验证码错误')


        # accesstoken判断
        tjs = TJS(settings.SECRET_KEY,300)

        # 解密前端带来的access_token值
        try:
            data = tjs.loads(attrs['access_token'])

        except:
            raise serializers.ValidationError('错误的access_token')

        # 通过access_token获取openid
        openid = data.get('openid')
        if openid is None:
            raise serializers.ValidationError('无效的access_token')

        # 添加对象
        attrs['openid'] = openid

        # 查询用户
        try:
            user = User.objects.get(mobile=attrs['mobile'])
        except:
            # 用户不存在
            return attrs
        else:
            # 用户存在
            if not user.check_password(attrs['password']):
                raise serializers.ValidationError('密码错误')
            attrs['user'] = user

            return attrs

        # 创建新用户
    def create(self,validated_data):
        # 判断是否有user
        user = validated_data.get('user')
        if user is None:
            user = User.objects.create_user(username=validated_data['mobile'], password=validated_data['password'],
                                           mobile=validated_data['mobile'],)
        # 绑定openid
        OAuthQQUser.objects.create(user=user,openid=validated_data['openid'])


        # 生成jwt token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 给user对象添加token属性
        user.token = token
        return user






